package ace.module.account.core.impl.manager.impl;

import ace.cmp.core.exception.BusinessException;
import ace.cmp.i18n.api.MessageSourceAssertService;
import ace.cmp.util.AceEnumUtils;
import ace.module.account.api.enums.IamAccountErrorEnum;
import ace.module.account.api.enums.IamAccountTagTypeEnum;
import ace.module.account.api.model.dto.IamAccountTagDto;
import ace.module.account.core.impl.dao.entity.IamAccountTag;
import ace.module.account.core.impl.dao.repository.IamAccountTagRepository;
import ace.module.account.core.impl.manager.IamAccountTagManager;
import ace.module.common.core.impl.manager.impl.AbstractEntityOfAppManager;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

/**
 * template author: caspar
 * template created at: 2023-12-18
 * template description: spring data jdbc querydsl rsql manager
 * generated at: 2024年6月24日 上午10:29:35
 * description: 账户标签 manager implement
 */
@Slf4j
@AllArgsConstructor
@Component
public class IamAccountTagManagerImpl
    extends AbstractEntityOfAppManager<IamAccountTag, Long, IamAccountTagDto>
    implements IamAccountTagManager {
  private final IamAccountTagRepository iamAccountTagRepository;
  private final MessageSourceAssertService assertService;

  @Transactional(rollbackFor = Exception.class)
  @Override
  public IamAccountTag addTag(
      Long iamAppId, Long accountId, String tagType, String tagKey, String tagValue) {
    IamAccountTag iamAccountTag = iamAccountTagRepository.getByIamAccountIdAndKey(accountId, tagKey);
    if (iamAccountTag != null) {
      this.checkTagTypeEquals(iamAccountTag.getType(), tagType);
      return iamAccountTag;
    }

    IamAccountTag newIamAccountTag =
        IamAccountTag.builder()
            .id(this.getNewId())
            .iamAppId(iamAppId)
            .iamAccountId(accountId)
            .type(tagType)
            .key(tagKey)
            .value(tagValue)
            .build();
    this.add(newIamAccountTag);
    return newIamAccountTag;
  }

  private void checkTagTypeEquals(String type, String type2) {
    this.checkTagType(type2);
    this.checkTagType(type);
    assertService.isTrue(
        !StringUtils.equals(type, type2),
        IamAccountTag.class.getName() + ".error-tag-type-exist",
        IamAccountErrorEnum.EXIST_EQUALS_KEY_BUT_NOT_EQUALS_TYPE_TAG.getDesc(),
        (message) -> {
          throw new BusinessException(
              IamAccountErrorEnum.EXIST_EQUALS_KEY_BUT_NOT_EQUALS_TYPE_TAG.getCode(), message);
        });
  }

  private void checkTagType(String type) {
    IamAccountTagTypeEnum iamAccountTagTypeEnum =
        AceEnumUtils.getEnum(IamAccountTagTypeEnum.class, type, null);
    assertService.isNull(
        iamAccountTagTypeEnum, IamAccountTag.class.getName() + ".error-tag-type", "请输入正确的标签类型");
  }
}
